package cn.hl.hm.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.filechooser.FileSystemView;

import cn.hl.hm.util.StringUtil;

/**
 * 文件处理类
 * 功能：文件存储、移动等等
 * @author Liuyc
 *
 */


public class FileUtil {

	
    
    /**
     * 获得文件的后缀
     * @param fileName  文件名
     * @return
     */
    public static String getFileSuffix(String fileName){  
        int splitIndex = fileName.lastIndexOf(".");  
        return fileName.substring(splitIndex + 1);  
    }  
	 
    /** 
     * 获取小图标 
     * sl.setIcon(getSmallIcon(f));  
        bl.setIcon(getBigIcon(f));  
     * @param f 
     * @return 
     */  
    public static Icon getSmallIcon(File f) {  
        if (f != null && f.exists()) {  
            FileSystemView fsv = FileSystemView.getFileSystemView();  
            return fsv.getSystemIcon(f);  
        }  
        return null;  
    }  
    
    /**
     * 获得文件小图标
     * @param sFile 具体的文件路径
     * @return
     */
    
    public static Icon getSmallIcon(String sFile) {  
    	File  f= new File(sFile);
        if (f != null && f.exists()) {  
            FileSystemView fsv = FileSystemView.getFileSystemView();  
            return fsv.getSystemIcon(f);  
        }  
        return null;  
    }  
      
    /** 
     * 获取大图标 
     * sl.setIcon(getSmallIcon(f));  
        bl.setIcon(getBigIcon(f));  
     * @param f 
     * @return 
     */  
    public static Icon getBigIcon(File f) {  
        if (f!=null && f.exists()) {  
            try {  
                sun.awt.shell.ShellFolder sf = sun.awt.shell.ShellFolder.getShellFolder(f);  
                return new ImageIcon(sf.getIcon(true));  
            } catch (FileNotFoundException e) {  
                e.printStackTrace();  
            }  
        }  
        return null;  
    }  
	
    
    /** 
     * 获取大图标 
     * sl.setIcon(getSmallIcon(f));  
        bl.setIcon(getBigIcon(f));  
     * @param sFile 文件的绝对路径
     * @return 
     */  
    public static Icon getBigIcon(String sFile) {  
    	File  f= new File(sFile);
        if (f!=null && f.exists()) {  
            try {  
                sun.awt.shell.ShellFolder sf = sun.awt.shell.ShellFolder.getShellFolder(f);  
                return new ImageIcon(sf.getIcon(true));  
            } catch (FileNotFoundException e) {  
                e.printStackTrace();  
            }  
        }  
        return null;  
    }  
	
	
    /**  
    * 判断文件是否存在.   
    * @param sFile  
    * @return  
    */  
    public static boolean isExist(String sFile) {  
       File objFile = new File(sFile);  
       if (objFile.exists()) {  
        return true;  
       } else {  
            return false;  
        }  
    }  

    
    /**  
    * 获得文件的路径
    * @param sFile  
    * @return  
    */  
    public static String getFilePath(String sFile) {  
    	String path="";
    	for(int i=sFile.length(); i>=0;i--)
    	{
    		sFile=sFile.replace("/", "\\");
    		String str=StringUtil.left(sFile, i);
    		str=StringUtil.right(str, 1);
    		if(str.equals("\\"))
    		{
    			path=StringUtil.left(sFile, i-1);
    			return path;
    		}
    	}
    	return path;
    }  
    
    
    /**  
    * 获得文件的文件扩展名
    * @param sFile  
    * @return  
    */  
    public static String getFileExt(String sFile) {  
    	String fileName="";
    	
    	for(int i=sFile.length(); i>=0;i--)
    	{
    		sFile=sFile.replace("/", "\\");
    		String str=StringUtil.left(sFile, i);
    		str=StringUtil.right(str, 1);
    		if(str.equals("."))
    		{
    			fileName=StringUtil.right(sFile, sFile.length()-i);
    			return fileName;
    		}
    	}
    	return fileName;
    }  
    
    /**  
    * 获得文件的主名（不含扩展名）
    * @param sFile  
    * @return  
    */  
    public static String getName(String fileName) {  
    	String name="";
    	for(int i=fileName.length(); i>=0;i--)
    	{
    		String str=StringUtil.subString(fileName, i, 1);
    		if(str.equals("."))
    		{
    			name=StringUtil.left(fileName, i);
    			break;
    		}
    	}
    	return name;
    }  
    
    
    /**  
    * 获得文件的文件名
    * @param sFile  
    * @return  
    */  
    public static String getFileName(String sFile) {  
    	String path="";
    	for(int i=sFile.length(); i>=0;i--)
    	{
    		sFile=sFile.replace("/", "\\");
    		String str=StringUtil.left(sFile, i);
    		str=StringUtil.right(str, 1);
    		if(str.equals("\\"))
    		{
    			path=StringUtil.right(sFile, sFile.length()-i);
    			return path;
    		}
    	}
    	return path;
    }  
    
    /**
     * 获得文件的长度
     * @param sFile
     * @return
     */
    public static Integer getFileLength(String sFile)
    {
		try {
			File myFile = new File(sFile.toString());
			Integer length=(int)myFile.length();
			return length;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
    }
    
	/**
	 * 删除文件
	 * @param strFile   String 文件路径及名称 如c:/fqf.txt
	 * @return true 删除成功
	 */
	public static boolean delFile(String strFile) {
		try {
			File myDelFile = new File(strFile.toString());
			myDelFile.delete();
			return true;
		} catch (Exception e) {
			System.out.println("删除文件操作出错");
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 读取到字节数组
	 * 
	 * @param filePath  要读取的文件
	 * @param isMax 是否大文件
	 * @return
	 * @throws IOException
	 */
	public static byte[] readFiletoByteArray(String filePath,boolean isMax) throws IOException {
		if(isMax)
			return toByteArray1(filePath);
		else
			return toByteArray2(filePath);
	}
	
	/**
	* 读取文本文件内容
	* @param strFile 带有完整绝对路径的文件名
	* @param encoding 文本文件打开的编码方式
	* @return 返回文本文件的内容
	*/
	   public static String readTextFile(String strFile,String encoding) throws IOException{
			encoding = encoding.trim();
			StringBuffer str = new StringBuffer("");
			String st = "";
			try{
				 FileInputStream fs = new FileInputStream(strFile);
				 InputStreamReader isr;
				 
				 if(encoding.equals("")){
					 isr = new InputStreamReader(fs);
				 }else{
					 isr = new InputStreamReader(fs,encoding);
				 }
				 BufferedReader br = new BufferedReader(isr);
				 try{
					 //开始读取文件内容
					 String data = "";
					 while((data = br.readLine())!=null){
						 str.append(data+""); 
					 	}
				 }
				 catch(Exception e){
					 e.printStackTrace();
				 }
				 br.close();
				 st = str.toString();
			}catch(IOException es){
				st = "";
			}
			return st;     
	   }

		/**
		* 读取文本文件内容
		* @param strFile 带有完整绝对路径的文件名
		* @param encoding 文本文件打开的编码方式
		* @return 返回文本文件的内容
		*/
		   public static String readTextFile(String strFile) throws IOException{
			   String encoding="utf-8";
			   return readTextFile(strFile,encoding);
		   }

	    /**
	     * 新建文件
	     * @param strFile 文本文件完整绝对路径及文件名
	     * @param fileContent 文本文件内容
	     * @return true 创建成功
	     */
	    public static boolean createTextFile(String strFile, String fileContent) {
	     
	        try {
	            File myFilePath = new File(strFile);
	            if (!myFilePath.exists()) {
	                myFilePath.createNewFile();
	            }
	            PrintWriter myFile = new PrintWriter(myFilePath,"utf-8");

	            myFile.println(fileContent);
	            myFile.close();
	            return true;
	        }
	        catch (Exception e) {
	        	e.printStackTrace();
	        }
	        return false;
	    }

	    /**
	     * 新建文件
	     * @param strFile 文本文件完整绝对路径及文件名
	     * @param fileContent 文本文件内容
	     * @return true 创建成功
	     */
	    public static boolean createFile(String strFile, byte[] fileContent) {
	     
		try {
			File myFilePath = new File(strFile);
			if (myFilePath.exists())
				myFilePath.delete();  //则文件删除
			
			myFilePath.createNewFile();
			// 建立输出字节流
			//创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true，则将字节写入文件末尾处，而不是写入文件开始处。
			FileOutputStream fos = new FileOutputStream(myFilePath);  //
			// 用FileOutputStream 的write方法写入字节数组
			fos.write(fileContent);
			// 为了节省IO流的开销，需要关闭
			fos.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	    
	    
	    /**
	     * 新建文件
	     * @param strFile 文本文件完整绝对路径及文件名
	     * @param fileContent 文本文件内容
	     * @return true 创建成功
	     */
	    public static boolean addFileByte(String strFile, byte[] fileContent) 
	    {
			try {
				File myFilePath = new File(strFile);
				if (myFilePath.exists())
				{
					// 建立输出字节流ff
					//创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true，则将字节写入文件末尾处，而不是写入文件开始处。
					FileOutputStream fos = new FileOutputStream(myFilePath,true);  //
					// 用FileOutputStream 的write方法写入字节数组
					fos.write(fileContent);
					// 为了节省IO流的开销，需要关闭
					fos.close();
					return true;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return false;
	}
	    /**
	     * 有编码方式的文件创建
	     * @param strFile 文本文件完整绝对路径及文件名
	     * @param fileContent 文本文件内容
	     * @param encoding 编码方式 例如 GBK 或者 UTF-8
	     * @return true 成功
	     */
	    public static boolean createTextFile(String strFile, String fileContent, String encoding) {
	     
	        try {
	            File myFilePath = new File(strFile);
	            if (!myFilePath.exists()) {
	                myFilePath.createNewFile();
	            }
	            PrintWriter myFile = new PrintWriter(myFilePath,encoding);
	            String strContent = fileContent;
	            myFile.println(strContent);
	            myFile.close();
	            return true;
	        }
	        catch (Exception e) {
	            e.printStackTrace();
	        }
	        return false;
	    } 
		
	    /**
	     * 有编码方式的文件创建
	     * @param strFile 文本文件完整绝对路径及文件名
	     * @param fileContent 文本文件内容
	     * @param encoding 编码方式 例如 GBK 或者 UTF-8
	     * @return true 成功
	     */
	public static boolean addTextFile(String strFile, String fileContent,
			String encoding) {

		try {
			File myFilePath = new File(strFile);
			if (myFilePath.exists()) {
				// 打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
				FileWriter writer = new FileWriter(myFilePath, true);
				writer.write(fileContent);
				writer.close();
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	    
			
	    /**
	     * 删除指定文件夹下所有文件
	     * @param strPath 文件夹完整绝对路径
	     * @return
	     * @return
	     */
	    public static boolean delAllFile(String strPath) {
	    	boolean b = false;
	        File file = new File(strPath);
	        if (!file.exists()) {   //如果不存在
	            return b;
	        }
	        if (!file.isDirectory()) {  //如果不是目录
	            return b;
	        }
	        
	        try
	        {
		        String[] tempList = file.list();
		        File temp = null;
		        for (int i = 0; i < tempList.length; i++) {
		            if (strPath.endsWith(File.separator)) {
		                temp = new File(strPath + tempList[i]);
		            }else{
		                temp = new File(strPath + File.separator + tempList[i]);
		            }
		            
		            if (temp.isFile()) { //如果是文件，删除
		                temp.delete();
		            }
		            
		            if (temp.isDirectory()) { //如果是目录，递归
		                delAllFile(strPath+"/"+ tempList[i]);//先删除文件夹里面的文件
		                
		                File f = new File(strPath+"/"+ tempList[i]);
		                f.delete();//再删除空文件夹
		                b = true;
		            }
		        }
	        }
	        catch(Exception e)
	        {
	        	e.printStackTrace();
	        }
	        return b;
	    }	
	
		/**
		 * 复制文件
		 * @param srcFile  源文件
		 * @param destFile  目标文件
		 * @param bOver 是否覆盖
		 * @return true 成功
		 * @throws IOException
		 */
		 public static boolean copyFile(String srcFile,String destFile,boolean bOver) throws IOException{
		     FileInputStream in=new FileInputStream(srcFile);
		     File file=new File(destFile);
		     try
		     {
			     if(!file.exists())
			     {
			         file.createNewFile();
			     }
			     else
			     {
			    	 //如果存在，则判断bOver值
			    	 if(bOver)
			    	 {
			    		 file.delete();  //删除文件
			    		 file.createNewFile();
			    	 }
			     }
			     
			     //开始读写文件
			     FileOutputStream out=new FileOutputStream(file);
			     int c;
			     byte buffer[]=new byte[1024];
			     while((c=in.read(buffer))!=-1){
			         for(int i=0;i<c;i++)
			             out.write(buffer[i]);        
			     }
			     in.close();
			     out.close();
			     
			     return true;
		     }
		     catch(Exception e)
		     {e.printStackTrace();}
		     
		     return false;
		 }	

		 /**
		  * 复制文件
		  * @param srcFile  源文件
		  * @param destFile  目标文件
		  * @return true  成功
		  */
		 public static boolean moveFile(String srcFile,String destFile)  throws IOException
		 {
			 if(copyFile(srcFile,destFile,false))
			 {
				 if(delFile(srcFile))
					 return true;
			 }
			 return false;
		 }
		 
		 
		 
		 /**
		  * 获得某个目录下所有文件
		  * @param strPath  某个目录
		  * @return 返回LIST列表
		  */
		 public static List<String> getFiles(String strPath)
		 {
			 	List<String> fl=new ArrayList<String>();
			 	
		        File file = new File(strPath);
		        if (!file.exists()) {   //如果不存在
		            return fl;
		        }
		        if (!file.isDirectory()) {  //如果不是目录
		            return fl;
		        }
		        
		        try
		        {
			        String[] tempList = file.list();
			        File temp = null;
			        for (int i = 0; i < tempList.length; i++) {
			            if (strPath.endsWith(File.separator)) {
			                temp = new File(strPath + tempList[i]);
			            }else{
			                temp = new File(strPath + File.separator + tempList[i]);
			            }
			            if (temp.isFile()) { //如果是文件，删除
			                fl.add(temp.toString());
			            }
			            
			            if (temp.isDirectory()) { //如果是目录，递归
			            	fl.addAll(getFiles(temp.toString()));
			            }
			        }
		        }
		        catch(Exception e)
		        {
		        	e.printStackTrace();
		        }
		        return fl;
		 }
		 
		 /**
		  * 获得某个目录下所有文件
		  * @param strPath  某个目录
		  * @param strExc  扩展名，如：  .exe,  .bat
		  * @return 返回LIST列表
		  */
		 public static List<String> getFiles(String strPath,String strExc)
		 {
			 	List<String> fl=new ArrayList<String>();
			 	
		        File file = new File(strPath);
		        if (!file.exists()) {   //如果不存在
		            return fl;
		        }
		        if (!file.isDirectory()) {  //如果不是目录
		            return fl;
		        }
		        
		        try
		        {
			        String[] tempList = file.list();
			        File temp = null;
			        for (int i = 0; i < tempList.length; i++) {
			            if (strPath.endsWith(File.separator)) {
			                temp = new File(strPath + tempList[i]);
			            }else{
			                temp = new File(strPath + File.separator + tempList[i]);
			            }
			            if (temp.isFile()) { //如果是文件，删除
			            	//判断文件扩展名是否是不是
			            	String prefix=temp.toString().substring(temp.toString().lastIndexOf("."));
			            	if(prefix.toUpperCase()==strExc.toUpperCase())   //如果扩展名相同   .exe=.exe
			            		fl.add(temp.toString());
			            }
			            
			            if (temp.isDirectory()) { //如果是目录，递归
			            	fl.addAll(getFiles(temp.toString(),strExc.toString()));
			            }
			        }
		        }
		        catch(Exception e)
		        {
		        	e.printStackTrace();
		        }
		        return fl;
		 }
	
	
	/**
	 * 读取到字节数组
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	private static byte[] toByteArray1(String filePath) throws IOException {

		File f = new File(filePath);
		if (!f.exists()) {
			throw new FileNotFoundException(filePath);
		}
		
		ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
		BufferedInputStream in = null;
		try {
			in = new BufferedInputStream(new FileInputStream(f));
			int buf_size = 1024;
			byte[] buffer = new byte[buf_size];
			int len = 0;
			while (-1 != (len = in.read(buffer, 0, buf_size))) {
				bos.write(buffer, 0, len);
			}
			return bos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			bos.close();
		}
	}

	/**
	 * 读取文件流到字节数组
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	public static byte[] stream2ByteArray(FileInputStream in) throws IOException {
		
		ByteArrayOutputStream bos = new ByteArrayOutputStream(0);
		try {
			int buf_size = 1024;
			byte[] buffer = new byte[buf_size];
			int lenght=in.read(buffer);
			bos = new ByteArrayOutputStream(lenght);
			int len = 0;
			while (-1 != (len = in.read(buffer, 0, buf_size))) {
				bos.write(buffer, 0, len);
			}
			return bos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			bos.close();
		}
	}
	
	
	/**
	 * 读取文件流到字节数组
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	public static byte[] stream2ByteArray(InputStream in) throws IOException {
		
		ByteArrayOutputStream bos = new ByteArrayOutputStream(0);
		try {
			int buf_size = 1024;
			byte[] buffer = new byte[buf_size];
			int lenght=in.read(buffer);
			bos = new ByteArrayOutputStream(lenght);
			int len = 0;
			while (-1 != (len = in.read(buffer, 0, buf_size))) {
				bos.write(buffer, 0, len);
			}
			return bos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			bos.close();
		}
	}
	/**
	 * Mapped File way MappedByteBuffer 可以在处理大文件时，提升性能
	 * 
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	private static byte[] toByteArray2(String filePath) throws IOException {

		FileChannel fc = null;
		RandomAccessFile rf = null;
		try {
			rf = new RandomAccessFile(filePath, "r");
			fc = rf.getChannel();
			MappedByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0,
					fc.size()).load();
			byte[] result = new byte[(int) fc.size()];
			if (byteBuffer.remaining() > 0) {
				byteBuffer.get(result, 0, byteBuffer.remaining());
			}
			return result;
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			try {
				rf.close();
				fc.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	
	
	
	
	
	
}
